package com.jianqiao.delivery.seventeentrack.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jianqiao.delivery.seventeentrack.domain.RegisterEventEntity;
import com.jianqiao.delivery.seventeentrack.domain.RegisterParamVo;
import com.jianqiao.delivery.seventeentrack.domain.SimplifiedTrackInfo;
import com.jianqiao.delivery.seventeentrack.domain.TrackEvent;
import com.jianqiao.delivery.seventeentrack.service.SeventeenTrackService;
import com.jianqiao.delivery.util.HttpClientUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.NameValuePair;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

import java.util.*;

/**
 * author: cyx
 * create: 2024/11/18 10:51
 **/
@Slf4j
@Service
public class SeventeenTrackServiceImpl implements SeventeenTrackService {

    @Value("${17track.url.register}")
    private String registerUrl;

    @Value("${17track.url.detail}")
    private String detailUrl;

    @Value("${17track.key}")
    private String key;

    @Override
    public String registerEvent(List<RegisterParamVo> paramList) {
        HashMap<String, String> paramMap = new HashMap<>();
        paramMap.put("17token" ,key);
        paramMap.put("Content-Type" ,"application/json");

        String paramStr = JSONObject.toJSONString(paramList);
        String resultStr = HttpClientUtil.doPostJson(registerUrl, paramStr ,paramMap);
        log.info("Get 17track register API result ->" + resultStr);
        return resultStr;
    }

    @Override
    public String detailEvent(List<RegisterParamVo> paramList) {
        HashMap<String, String> paramMap = new HashMap<>();
        paramMap.put("17token" ,key);
        paramMap.put("Content-Type" ,"application/json");

        String paramStr = JSONObject.toJSONString(paramList);
        String resultStr = HttpClientUtil.doPostJson(detailUrl, paramStr, paramMap);
        log.info("Get 17track detail API result ->" + resultStr + "\n");

        // 解析结果并简化
        SimplifiedTrackInfo simplifiedInfo = parseAndSimplify(resultStr);
        log.info("Get 17track detail API result ->" + simplifiedInfo + "\n");

        //提取时间,地点,描述，以"/"分隔
        String formattedInfo = formatSimplifiedTrackInfo(simplifiedInfo);

        log.info("Get 17track detail API result ->" + formattedInfo);
        return formattedInfo;
    }

    /**
    * @Description: 将 resultStr 这个复杂的结果简化为一个个简单的event，每个event只包含 时间、地点、描述 这三个元素
    * @Author: lsx
    * @Date: 2024/12/3 15:22
    **/
    private SimplifiedTrackInfo parseAndSimplify(String resultStr) {
        JSONObject resultJson = JSON.parseObject(resultStr);
        SimplifiedTrackInfo simplifiedInfo = new SimplifiedTrackInfo();

        if (resultJson.getIntValue("code") == 0) {
            JSONObject data = resultJson.getJSONObject("data");
            if (data != null && data.getJSONArray("accepted") != null) {
                for (Object acceptedObj : data.getJSONArray("accepted")) {
                    // 提取最新事件的时间、地点、描述
                    JSONObject accepted = (JSONObject) acceptedObj;
//                    String number = accepted.getString("number");
//                    String carrier = accepted.getString("carrier");
//                    String latestStatus = accepted.getJSONObject("track_info").getJSONObject("latest_status").getString("status");
                    String latestDescription = accepted.getJSONObject("track_info").getJSONObject("latest_event").getString("description");
                    String latestLocation = accepted.getJSONObject("track_info").getJSONObject("latest_event").getString("location");
                    String latestTime = accepted.getJSONObject("track_info").getJSONObject("latest_event").getString("time_iso");

                    // 提取以往事件的时间、地点、描述
                    List<TrackEvent> trackEvents = new ArrayList<>();
                    JSONObject tracking = accepted.getJSONObject("track_info").getJSONObject("tracking");
                    if (tracking != null) {
                        JSONArray providers = tracking.getJSONArray("providers");
                        if (providers != null) {
                            for (Object providerObj : providers) {
                                JSONObject provider = (JSONObject) providerObj;
                                JSONArray events = provider.getJSONArray("events");
                                if (events != null) {
                                    for (Object eventObj : events) {
                                        JSONObject event = (JSONObject) eventObj;
                                        TrackEvent trackEvent = new TrackEvent();
                                        String time = event.getString("time_iso");
                                        trackEvent.setTime(formatTime(time));
                                        trackEvent.setDescription(event.getString("description"));
                                        trackEvent.setLocation(event.getString("location"));
                                        trackEvents.add(trackEvent);
                                    }
                                } else {
                                    log.warn("Events array is null or empty for number: ");
                                }
                            }
                        } else {
                            log.warn("Providers array is null or empty for number: ");
                        }
                    } else {
                        log.warn("Tracking object is null for number: ");
                    }

//                    simplifiedInfo.setNumber(number);
//                    simplifiedInfo.setCarrier(carrier);
//                    simplifiedInfo.setLatestStatus(latestStatus);
                    //目前不需要最新事件，注释
//                    simplifiedInfo.setLatestTime(formatTime(latestTime));
//                    simplifiedInfo.setLatestLocation(latestLocation);
//                    simplifiedInfo.setLatestDescription(latestDescription);
                    simplifiedInfo.setTrackEvents(trackEvents);
                }
            }
        }
        return simplifiedInfo;
    }

    /**
    * @Description: 将原本 yyyy-MM-dd'T'HH:mm:ssXXX 的时间转化为 yyyy-MM-dd HH:mm:ss
    * @Author: lsx
    * @Date: 2024/12/3 15:24
    **/
    public String formatTime(String time) {
        // 定义输入格式
        DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX");
        // 解析时间字符串
        ZonedDateTime zonedDateTime = ZonedDateTime.parse(time, inputFormatter);
        // 定义输出格式
        DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // 格式化时间
        return zonedDateTime.format(outputFormatter);
    }

    /** 
    * @Description: 将每个event里的时间、地点、描述 以"/"分隔，如: 2024-11-23 10:22:22/泉州市,泉州转运中心/【泉州市】 快件已发往 福建中涵/
    * @Author: lsx
    * @Date: 2024/12/3 15:30
    **/
    public String formatSimplifiedTrackInfo(SimplifiedTrackInfo simplifiedInfo) {
        StringBuilder formattedInfo = new StringBuilder();

        // 处理最新事件
//        formattedInfo.append(simplifiedInfo.getLatestTime())
//                .append("\t")
//                .append(simplifiedInfo.getLatestLocation())
//                .append("\t")
//                .append(simplifiedInfo.getLatestDescription())
//                .append("\t")
//                .append("\n");

        // 如果有跟踪事件列表，则遍历并处理每个事件
        if (simplifiedInfo.getTrackEvents() != null && !simplifiedInfo.getTrackEvents().isEmpty()) {
            List<TrackEvent> trackEvents = simplifiedInfo.getTrackEvents();

            // 将事件按时间升序
            Collections.sort(trackEvents, Comparator.comparing(TrackEvent::getTime));

            // 遍历事件，输出事件结果
            for (TrackEvent event : trackEvents) {
                formattedInfo.append("\n")
                        .append(event.getTime())
                        .append("\t")
                        .append(event.getLocation())
                        .append("\t")
                        .append(event.getDescription())
                        .append("\t");
            }
        }
        // 返回最终的格式化字符串
        return formattedInfo.toString();
    }
}
